package GUI;


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayOutputStream;
import java.io.CharArrayWriter;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import java.awt.Desktop;
import java.awt.Font;
import javax.swing.JTextField;

import client.*;

import Library.*;
import Server.*;


/** this class produce activity report, save it to file and send path to server
 *  to save in db*/
public class GUI_ActivityReport extends JPanel
{
	/**clc instance of ClientConsole*/
	private ClientConsole clc;
	/**table table to display results*/
	private JTable table;
	/**table2 table to display results*/
	private JTable table2;
	/**list ArrayList to get results from server*/
	private ArrayList<String[]> list;
	/**textField to get from date*/
	private JTextField textField;
	/**textField to get to date*/
	private JTextField textField_1;
	private String from;
	private String to;
	private JLabel lblFromddmmyyyy;
	private JLabel lblToddmmyyyy;
	private JButton btnGetReport;
	private JButton btnExistingReports;
	/**file to print report to*/
	private char file[];
	/**stream to save to char array*/
	private CharArrayWriter chw;
	/**stream to print to char array*/
	private PrintWriter pw;
	/**stream to char array to file*/
	private FileWriter fw;
	/**textField to get report id to display*/
	private JTextField textField_2;
	/**counter for number of loans in week 1 of the week*/
	public int week1=0;
	/**counter for number of loans in week 2 of the week*/
	public int week2=0;
	/**counter for number of loans in week 3 of the week*/
	public int week3=0;
	/**counter for number of loans in week 4 of the week*/
	public int week4=0;
	/**ArrayList for result of loans per week*/
	public ArrayList<Integer> weekRes;
	
	/**@param cc current ClientConsole
	 * @param gl instance of current GUI_LogIn
	 * @param r instance of current GUI_Report*/
	public GUI_ActivityReport(ClientConsole cc, final GUI_LogIn gl,final GUI_Report r)
	{
		this.setSize(700,600);
		setLayout(null);
		clc=cc;
		
		chw=new CharArrayWriter();
		pw=new PrintWriter(chw);
		JButton btnBack = new JButton("Back");
		btnBack.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				gl.setContentPane(r);
			}
		});
		btnBack.setBounds(461, 423, 89, 23);
		add(btnBack);
		
		JButton btnLogOut = new JButton("Log Out");
		btnLogOut.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				gl.LogOut();
			}
		});
		btnLogOut.setBounds(565, 423, 89, 23);
		add(btnLogOut);
		
		JLabel lblActivityReport = new JLabel("Activity Report");
		lblActivityReport.setFont(new Font("Tahoma", Font.BOLD, 14));
		lblActivityReport.setBounds(302, 0, 159, 36);
		add(lblActivityReport);
		
		lblFromddmmyyyy = new JLabel("From (yyyy/mm/dd):");
		lblFromddmmyyyy.setBounds(22, 96, 136, 23);
		add(lblFromddmmyyyy);
		
		textField = new JTextField();
		textField.setBounds(168, 97, 113, 20);
		add(textField);
		textField.setColumns(10);
		
		lblToddmmyyyy = new JLabel("To (yyyy/mm/dd):");
		lblToddmmyyyy.setBounds(22, 130, 136, 23);
		add(lblToddmmyyyy);
		
		textField_1 = new JTextField();
		textField_1.setBounds(168, 128, 113, 20);
		add(textField_1);
		textField_1.setColumns(10);
		
		btnGetReport = new JButton("Get Report");
		btnGetReport.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				from=textField.getText();
				to=textField_1.getText();
				DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
				Calendar cal = Calendar.getInstance();
				dateFormat.setLenient(false);
				try {
					Date dt=dateFormat.parse(to);
					Date df=dateFormat.parse(from);
					String todayS=dateFormat.format(cal.getTime());
					Date today=dateFormat.parse(todayS);
					if(dt.after(today))
					{
						JOptionPane.showMessageDialog(new JFrame(),"Date To must be maximum today.\nPlease enter a new date");
						textField_1.setText("");
						return;
					}
					if(df.after(dt))
					{
						JOptionPane.showMessageDialog(new JFrame(),"Date From must be before date To.\nPlease enter a new date");
						textField.setText("");
						return;
					}
				} catch (ParseException e1) {
					// TODO Auto-generated catch block
					JOptionPane.showMessageDialog(new JFrame(),"Incorrect input.\nPlease enter new dates");
					textField.setText("");
					textField_1.setText("");
					return;
				}
				
				remove(textField);
				remove(textField_1);
				remove(lblFromddmmyyyy);
				remove(lblToddmmyyyy);
				remove(btnGetReport);
				remove(btnExistingReports);
				repaint();
				
				countByReaderCardStatus();
				countByLoanedCopies();
				lateInReturn();
				String newFrom="";
				String newTo="";
				for(int i=0;i<from.length();i++)
				{
					if(from.charAt(i)=='/') newFrom+='.';
					else newFrom+=from.charAt(i);
				}
				for(int i=0;i<to.length();i++)
				{
					if(to.charAt(i)=='/') newTo+='.';
					else newTo+=to.charAt(i);
				}
				try {
					Report r=new Report(file,"activity",newFrom,newTo);
					clc.client.sendToServer(r);
					while(clc.client.flag==0)
						System.out.println("");
					clc.client.flag=0;
					boolean res=(boolean) clc.client.message;
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		btnGetReport.setBounds(22, 185, 125, 23);
		add(btnGetReport);
		
		btnExistingReports = new JButton("Choose an existing report");
		btnExistingReports.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				remove(textField);
				remove(textField_1);
				remove(lblFromddmmyyyy);
				remove(lblToddmmyyyy);
				remove(btnGetReport);
				remove(btnExistingReports);
				repaint();
				
				displayReports();
			}
		});
		btnExistingReports.setBounds(22, 257, 234, 23);
		add(btnExistingReports);	

	}
	
	/**this method display previous reports to choose from*/
	public void displayReports()
	{
		try {
			String s[]={"getReports"};
			clc.client.sendToServer(s);
			while(clc.client.flag==0)
				System.out.print("");
			clc.client.flag=0;
			list=clc.client.details;
			
			JLabel lblChooseReport = new JLabel("Enter report id to display:");
			lblChooseReport.setBounds(22, 257,200, 23);
			add(lblChooseReport);
			
			textField_2 = new JTextField();
			textField_2.setBounds(210, 257, 90, 23);
			add(textField_2);
			textField_2.setColumns(10);
			
			JScrollPane scrollPane = new JScrollPane();
			scrollPane.setBounds(10, 46, 551, 136);
			add(scrollPane);
			table2 = new JTable(list.size(),2);
			table2.getColumnModel().getColumn(0).setHeaderValue("Report ID");
			table2.getColumnModel().getColumn(1).setHeaderValue("Report");
			scrollPane.setViewportView(table2);
			
			for(int i=0;i<list.size();i++)
			{
				for(int j=0;j<2;j++)
				{
					table2.setValueAt(list.get(i)[j],i,j);
				}
			}
			
			JButton btnGetReport_1 = new JButton("Get Report");
			btnGetReport_1.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					if(textField_2.getText().equals(""))
					{
						JOptionPane.showMessageDialog(new JFrame(),"Incorrect input");
						return;
					}
					String[] s2={"getReport",textField_2.getText()};
					try {
						clc.client.sendToServer(s2);
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					while(clc.client.flag==0)
						System.out.print("");
					clc.client.flag=0;
					byte[] fileBytes=(byte[]) clc.client.message;
					clc.client.message=null;
					
					Desktop d=Desktop.getDesktop();
					FileOutputStream targetFile;
					System.out.println(fileBytes.length);
					String target="c:/files/tempContent2.txt";
					try {
					targetFile = new FileOutputStream(target);
					targetFile.write(fileBytes);
		            targetFile.close();
		            File f=new File(target);
		            d.open(f);
					} catch (FileNotFoundException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					} catch (IOException e2) {
						// TODO Auto-generated catch block
						e2.printStackTrace();
					}
				}
			});
			btnGetReport_1.setBounds(372, 257,100, 23);
			add(btnGetReport_1);
			
			
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		if(list.size()>0) list.removeAll(list);
	}
	
	/**this method display number of reader cards in each status*/
	public void countByReaderCardStatus()/*Number of reader cards by status*/
	{
		JLabel lblNumberOfUsers = new JLabel("Number of reader cards active/frozen/not active/frozenUntil:");
		lblNumberOfUsers.setBounds(10, 21, 400, 31);
		add(lblNumberOfUsers);
		try {
			String s[]={"countByReaderCardStatus"};
			clc.client.sendToServer(s);
			while(clc.client.flag==0)
				System.out.print("");
			clc.client.flag=0;
			list=clc.client.details;
			
			JScrollPane scrollPane = new JScrollPane();
			scrollPane.setBounds(10, 46, 551, 136);
			add(scrollPane);
			table = new JTable(list.size(),2);
			table.getColumnModel().getColumn(0).setHeaderValue("Status");
			table.getColumnModel().getColumn(1).setHeaderValue("Number of Reader Cards");
			scrollPane.setViewportView(table);
			
			pw.print("Number of reader cards active/frozen/not active/frozenUntil: ");
			for(int i=0;i<list.size();i++)
			{
				for(int j=0;j<2;j++)
				{
					table.setValueAt(list.get(i)[j],i,j);
					pw.write(list.get(i)[j]+" ");
				}
			}
			pw.println();
			file=chw.toCharArray();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		if(list.size()>0) list.removeAll(list);
	}
	
	/**this method display number of total loaned copies*/
	public void countByLoanedCopies()/*Number of loaned copies*/
	{
		JLabel lblNumberOfLoaned = new JLabel("Number of loaned copies:");
		lblNumberOfLoaned.setBounds(10, 188, 233, 23);
		add(lblNumberOfLoaned);
		
		JTextArea textArea = new JTextArea();
		textArea.setBounds(177,190,10, 15);//168, 97, 113, 20
		textArea.setBackground(getBackground());
		add(textArea);
		
		try {
			String s[]={"countByLoanedCopies",from,to};
			clc.client.sendToServer(s);
			while(clc.client.flag==0)
				System.out.print("");
			clc.client.flag=0;
			Integer res=(Integer)clc.client.message;
			System.out.println("res="+res);
			textArea.append(res.toString());
			
			pw.println("Number of loaned copies: "+res.toString());
			file=chw.toCharArray();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
	
	/**this method display number of members that are late in returning their books*/
	public void lateInReturn()/*Number of members that are late in returning their books*/
	{
		JLabel lblNumberOfMembers = new JLabel("Number of members that are late in returning their books:");
		lblNumberOfMembers.setBounds(10, 210, 333, 23);
		add(lblNumberOfMembers);
		
		JTextArea textArea = new JTextArea();
		textArea.setBounds(350, 212, 72, 15);
		textArea.setBackground(getBackground());
		add(textArea);
		
		try {
			String s[]={"countLateInReturns",from,to};
			clc.client.sendToServer(s);
			while(clc.client.flag==0)
				System.out.print("");
			clc.client.flag=0;
			Integer res=(Integer)clc.client.message;
			textArea.append(res.toString());
			
			pw.println("Number of members that are late in returning their books: "+res.toString());
			file=chw.toCharArray();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
	
	/**@param month
	 * @ year
	 * @return average of number of copies in loan in a given month of a given year*/
	public double AvgOfNumberOfCopiesInLoan(String month,String year)
	{
		GetNumOfLoanedCopies(month,year);
		return (double)((week1+week2+week3+week4)/4);
	}
	
	/**@param month
	 * @ year
	 * @return median of number of copies in loan in a given month of a given year*/
	public int MedianOfNumberOfCopiesInLoan(String month,String year)
	{
		GetNumOfLoanedCopies(month,year);
		weekRes=new ArrayList<Integer>();
		weekRes.add(week1);
		weekRes.add(week2);
		weekRes.add(week3);
		weekRes.add(week4);
		ArrayList<Integer> ToSort=new ArrayList<Integer>(weekRes);
		Collections.sort(ToSort);
		return ToSort.get(2);
	}
	
	/**
	 * @param status
	 * @return number of reader cards in a given status*/
	public int GetNumOfReadersPerStatus(String status)
	{
		Statement stmt;
		try 
			{
				stmt = EchoServer.conn.createStatement();
				ResultSet rs = stmt.executeQuery("SELECT COUNT(readerId) FROM readercard WHERE status='"+status+"';");
				if(rs.next())
		 		{
		 			return rs.getInt(1);
		 		}
			}
		catch (SQLException e) {e.printStackTrace();}
		return 0;
	}
	
	/**
	 * @param month
	 * @param year
	 * this method returns number of loaned copies*/
	public void GetNumOfLoanedCopies(String month,String year)
	{
		Statement stmt;
		int res=0;
		try {	
			stmt = EchoServer.conn.createStatement();
			ResultSet rs = stmt.executeQuery("SELECT * FROM loans l");
	 		while(rs.next())
	 		{
	 			if((rs.getString(3).substring(0,4).equals(year))&&(rs.getString(3).substring(5,7).equals(month)))
	 			{
	 				int day=Integer.parseInt(rs.getString(3).substring(8, 10));
	 				if(day>=1&&day<=7)
	 					week1++;
	 				if(day>=8&&day<=14)
	 					week2++;
	 				if(day>=15&&day<=21)
	 					week3++;
	 				if(day>=22&&day<=28)
	 					week4++;
	 			}
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
